<template>
  <div class="ticket-info-main">
    <span class="ticet-title">{{ businessData.name || "" }}业务工单 - {{ flowTypeList[flowType] }}</span>
    <el-form ref="formRef" :model="formCustom" status-icon :rules="rules" label-width="auto">
      <el-row :gutter="50">
        <el-col :span="12">
          <el-form-item label="工单标题" prop="name">
            <el-input v-model="formCustom.name" type="text" autocomplete="off" :disabled="!submitUser" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="发起时间" prop="create_at">
            <el-input v-model="formCustom.create_at" type="text" autocomplete="off" disabled />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="50">
        <el-col :span="12">
          <el-form-item label="紧急程度" prop="priority">
            <el-select v-model="formCustom.priority" :disabled="!submitUser && !(isRejectedByNoA && isCurUser)">
              <el-option v-for="item in priorityList" :key="item.key" :label="item.name" :value="item.key"></el-option>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="发起人" prop="create_by">
            <el-input v-model="formCustom.create_by" type="text" autocomplete="off" disabled />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="50">
        <el-col :span="12">
          <el-form-item label="工单编号" prop="id">
            <el-input v-model="formCustom.id" type="text" autocomplete="off" disabled />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="工单状态" prop="status">
            <el-input v-model="formCustom.status" type="text" autocomplete="off" disabled />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="50">
        <el-col :span="24">
          <el-form-item label="工单说明" prop="desc">
            <el-input
              v-model="formCustom.desc"
              type="textarea"
              :rows="8"
              autocomplete="off"
              maxlength="888"
              show-word-limit
              :disabled="!submitUser && !(isRejectedByNoA && isCurUser)"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="50">
        <el-col :span="24">
          <el-form-item label="上传附件" prop="attachment">
            <div class="file-block">
              <div v-if="submitUser || (isRejectedByNoA && isCurUser)">
                <UploadFile
                  :file-list="formCustom.attachment"
                  @update-file-list="updateFileList"
                  :import-api="uploadPdfApi"
                ></UploadFile>
              </div>
              <div class="file-block-content">
                <div v-for="(item, i) in formCustom.attachment" :key="i" class="file-block-item">
                  <el-button type="primary" :icon="Paperclip" link @click="openFile(item)">
                    <div class="name">{{ item.name }}</div>
                  </el-button>
                  <el-button class="icon-down" type="primary" :icon="Download" link @click="downloadFile(item)"></el-button>
                  <el-button
                    v-if="submitUser || (isRejectedByNoA && isCurUser)"
                    class="icon-del"
                    type="primary"
                    :icon="Delete"
                    link
                    @click="deleteFile(i)"
                  ></el-button>
                </div>
              </div>
            </div>
          </el-form-item>
        </el-col>
      </el-row>
      <div v-if="ticketType === 'alarm'">
        <div class="min-title">
          <div class="icon"></div>
          <div class="text">关联告警</div>
        </div>
        <ProTable
          :key="new Date().getTime()"
          ref="proTableAlarm"
          highlight-current-row
          :columns="alarmColumns"
          :request-api="getAlarmListApi"
          :pagination="false"
          :show-summary="false"
          :indent="20"
          :search-col="{ xs: 1, sm: 1, md: 2, lg: 4, xl: 4 }"
          :init-param="alarmInitParams"
        >
          <template #operation="">
            <el-button type="primary" link>详情</el-button>
          </template>
        </ProTable>
      </div>
      <div v-if="ticketType === 'asset'">
        <div class="min-title">
          <div class="icon"></div>
          <div class="text">关联资产</div>
        </div>
        <div style="margin-top: -20px">
          <ProTable
            :key="new Date().getTime()"
            ref="proTableAsset"
            highlight-current-row
            :columns="assetColumns"
            :request-api="getAssetListApi"
            :pagination="false"
            :show-summary="false"
            :indent="20"
            :search-col="{ xs: 1, sm: 1, md: 2, lg: 4, xl: 4 }"
            :init-param="assetInitParams"
          >
          </ProTable>
        </div>
      </div>
      <div class="min-title">
        <div class="icon"></div>
        <div class="text">关联业务</div>
      </div>
      <el-row :gutter="50">
        <el-col :span="12">
          <el-form-item label="业务模块" prop="module">
            <el-select
              v-model="formCustom.module"
              autocomplete="off"
              :disabled="ticketType === 'normal'"
              @change="formCustom.business_id = null"
            >
              <el-option v-for="(list, key, i) in businessList" :label="list[0].module_zh" :value="key" :key="i"></el-option>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="关联资源" prop="source_type">
            <el-select
              v-model="formCustom.source_type"
              autocomplete="off"
              clearable
              :disabled="!submitUser && !(isRejectedByNoA && isCurUser)"
            >
              <el-option
                v-for="item in relatedResourcesList"
                :key="item.value"
                :label="item.name"
                :value="item.value"
              ></el-option>
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="50">
        <el-col :span="12">
          <el-form-item label="业务类型" prop="business_id">
            <el-select
              v-model="formCustom.business_id"
              autocomplete="off"
              :disabled="ticketType === 'normal'"
              @change="businessIdChange()"
            >
              <el-option
                v-for="(item, i) in businessList[formCustom.module] || []"
                :label="item.name"
                :value="item.id"
                :key="i"
              ></el-option>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="资源ID" prop="source_id">
            <el-input
              v-model="formCustom.source_id"
              type="text"
              autocomplete="off"
              :disabled="!submitUser && !(isRejectedByNoA && isCurUser)"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="50">
        <el-col :span="12">
          <el-form-item label="关联资产编号" prop="asseet_no">
            <el-input
              v-model="formCustom.asseet_no"
              type="text"
              autocomplete="off"
              :disabled="!submitUser && !(isRejectedByNoA && isCurUser)"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="50">
        <el-col :span="24">
          <el-form-item label="处理意见" prop="notes">
            <el-input
              v-model="formCustom.notes"
              type="textarea"
              :rows="8"
              autocomplete="off"
              maxlength="888"
              show-word-limit
              :disabled="!submitUser && !(isRejectedByNoA && isCurUser)"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="50">
        <el-col :span="24">
          <el-form-item label="快捷操作" prop="desc">
            <div class="quick-operation">
              <div v-for="(item, i) in quickOperationList" :key="i">
                <span class="name">{{ item.name }}</span>
                <el-link class="btn" type="primary">详情</el-link>
              </div>
            </div>
          </el-form-item>
        </el-col>
      </el-row>
      <div class="min-title">
        <div class="icon"></div>
        <div class="text">关联流程</div>
      </div>
      <el-row :gutter="50">
        <el-col :span="24">
          <el-form-item label="选择流程" prop="workflow">
            <div style="display: flex; width: 100%">
              <el-select v-model="formCustom.workflow" autocomplete="off" :disabled="!submitUser">
                <el-option v-for="item in workflowList" :key="item.id" :label="item.name" :value="item.id"></el-option>
              </el-select>
              <el-button type="primary" link style="margin-left: 16px" @click="showFlow()">查看</el-button>
            </div>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="50">
        <el-col :span="24">
          <el-form-item label="流程意见" prop="opinion" v-if="isNew || isCurUser">
            <el-input v-model="formCustom.opinion" type="textarea" :rows="8" autocomplete="off" maxlength="888" show-word-limit />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <el-tabs v-model="tabsMenuValue" v-if="!isNew">
      <el-tab-pane label="审核意见" name="A">
        <OpinionDetail :data="opinionList[0]" :tag="'审'"></OpinionDetail>
      </el-tab-pane>
      <el-tab-pane label="处理意见" name="B">
        <OpinionDetail :data="opinionList[1]" :tag="'处'"></OpinionDetail>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<script setup lang="ts">
import { watch, computed, reactive, ref, onMounted } from "vue";
import { Paperclip, Delete, Download } from "@element-plus/icons-vue";
import type { FormInstance, FormRules } from "element-plus";
import OpinionDetail from "./OpinionDetail.vue";
import { useUserStore } from "@/stores/modules/user";
import ProTable from "@/components/ProTable/index.vue";
import UploadFile from "./UploadFile.vue";
import { ColumnProps } from "@/components/ProTable/interface";
import {
  getAssetListApi,
  getAssetFiledApi,
  getAlarmListApi,
  getBusinessListApi,
  getWorkflowListApi
} from "@/api/modules/ticket/pending";
import { uploadPdfApi } from "@/api/modules/sysManagement/noticeManagement";
import moment from "moment";
export interface TicketInfoProps {
  assetApi?: (params: any) => Promise<any>; // 请求表格数据的 api ==> 非必传
  ticketData: any;
  businessData: any;
  flowType?: string;
  ticketType?: string;
  assetInitParams?: any;
  alarmInitParams?: any;
}
const props = withDefaults(defineProps<TicketInfoProps>(), {
  ticketData: {},
  businessData: {},
  flowType: "NEW",
  ticketType: "normal",
  assetInitParams: {},
  alarmInitParams: {}
});
// const props = defineProps({
// const props = defineProps({
//   ticketData: {
//     type: Object,
//     require: true,
//     default: () => ({})
//   },
//   businessData: {
//     type: Object,
//     require: true,
//     default: () => ({})
//   },
//   assetData: {
//     type: Array,
//     require: true,
//     default: () => []
//   },
//   flowType: {
//     type: String,
//     require: false,
//     default: "NEW"
//   },
//   ticketType: {
//     type: String,
//     require: false,
//     default: "normal"
//   },
//   assetInitParams: {
//     type: Object as any
//   }
// });

const userStore = useUserStore();
const userInfo = computed(() => userStore.userInfoGet);
const userName = userInfo.value.username;
const nowDate = moment(new Date()).format("YYYYMMDD");
const tabsMenuValue = ref("A");
const priorityList = [
  { key: "3", name: "特急", color: "rgba(240, 104, 105)" },
  { key: "2", name: "紧急", color: "rgba(251, 178, 37)" },
  { key: "1", name: "一般", color: "rgba(66, 204, 178)" }
];
const statusList = reactive({
  REVIEW: "审核中",
  PENDING: "处理中",
  REJECTED: "已退回",
  REVOKED: "已撤回",
  FINISHED: "完成"
});
const relatedResourcesList = [
  { name: "云主机", value: "云主机" },
  { name: "云硬盘", value: "云硬盘" },
  { name: "云网络", value: "云网络" },
  { name: "弹性IP", value: "弹性IP" },
  { name: "弹性负载均衡", value: "弹性负载均衡" },
  { name: "弹性云服务器网卡", value: "弹性云服务器网卡" },
  { name: "带宽", value: "带宽" },
  { name: "NAT网关", value: "NAT网关" },
  { name: "安全组件", value: "安全组件" },
  { name: "应用", value: "应用" },
  { name: "告警", value: "alarm" }
];
// 是否是新建流程
const isNew = computed(() => props.flowType === "NEW");
// 是否是撤回流程
const isRevoked = computed(() => ["REVOKED"].includes(props.flowType));
// 退回的人是否是管理员
const isAdminReject = computed(() => props.ticketData.reject_user && props.ticketData.reject_user.is_admin);
// 是否是非管理员退回流程
const isRejectedByNoA = computed(() => ["REJECTED"].includes(props.flowType) && !isAdminReject.value);
// 是否是管理员退回流程
const isRejectedByA = computed(() => ["REJECTED"].includes(props.flowType) && isAdminReject.value);
// 审核处理流程
// const isHandle = computed(() => ["REVIEW", "PENDING"].includes(props.flowType));
// 是否是当前流程处理人
const isCurUser = computed(() => (props.ticketData.current_operator || []).includes(userName));
// 新建、撤回、admin退回至发起人流程中的发起人(当前流程处理人)
const submitUser = computed(
  () => isNew.value || (isRevoked.value && isCurUser.value) || (isRejectedByA.value && isCurUser.value)
);
// const quickOperationList = computed(() => props.businessData.instruction || []);
// const workflowList = computed(() => props.businessData.workflow || []);
const quickOperationList = ref<any>([]);
// 流程
const baseWorkflow = ref([
  {
    id: 0,
    name: "通用"
  }
]);
const workflowList = ref<any>(baseWorkflow.value);
// 审批流程意见、处理流程意见
const opinionList = ref<any>([[], []]);
// 业务类型选项
const businessList = ref<any>({});
const flowTypeList = reactive({
  NEW: "新建",
  REVIEW: "审核",
  PENDING: "处理",
  REVOKED: "审核",
  REJECTED: "审核",
  FINISHED: "审核"
});
const formRef = ref<FormInstance>();
let formCustom = reactive<any>({
  name: props.businessData.name + "_" + userName + "_" + nowDate,
  create_at: nowDate,
  priority: "1",
  create_by: userName,
  id: "",
  status: "",
  desc: "",
  module: props.businessData.module,
  business_id: props.businessData.id,
  source_type: "",
  source_id: "",
  asseet_no: "",
  notes: props.businessData.notes,
  opinion: "",
  workflow: "",
  attachment: []
});
const rules = reactive<FormRules<typeof formCustom>>({
  name: [
    { required: true, message: "不能为空", trigger: "blur" },
    { required: true, message: "长度需为1~288个字符", min: 1, max: 288, trigger: "blur" }
  ],
  priority: [{ required: true, message: "不能为空", trigger: "change" }],
  desc: [{ min: 0, max: 888, message: "长度需为0~888个字符", trigger: "blur" }],
  module: [{ required: true, message: "不能为空", trigger: "change" }],
  business_id: [{ required: true, message: "不能为空", trigger: "change" }],
  source_id: [
    { required: false, message: "不能为空", trigger: "blur" },
    { required: false, message: "长度需为0~288个字符", min: 0, max: 288, trigger: "blur" }
  ],
  asseet_no: [{ min: 0, max: 288, message: "长度需为0~288个字符", trigger: "blur" }],
  notes: [{ min: 0, max: 888, message: "长度需为0~888个字符", trigger: "blur" }],
  workflow: [{ required: true, message: "不能为空", trigger: "change" }],
  opinion: [
    { required: true, message: "不能为空", trigger: "blur" },
    { required: true, message: "长度需为1~888个字符", min: 1, max: 888, trigger: "blur" }
  ]
});
// const fileList = ref([
//   { name: "监控数据采集汇总监控数据采集汇总监控数据采集汇总监控数据采集汇总0467", link: "" },
//   { name: "监控数据采集汇总0920", link: "" },
//   { name: "监控数据采集汇总1020", link: "" },
//   { name: "监控数据采集汇总0923", link: "" },
//   { name: "监控数据采集汇总0615", link: "" }
// ]);
// 表格配置项
let assetColumns = ref<ColumnProps[]>([]);
let alarmColumns = reactive<ColumnProps[]>([
  { prop: "system_name", label: "来源模块", minWidth: 150 },
  { prop: "importance", label: "重要程度", minWidth: 150 },
  { prop: "level_type", label: "告警等级", minWidth: 150 },
  { prop: "name", label: "告警名称", minWidth: 200 },
  { prop: "sid", label: "告警流水号", minWidth: 200 },
  { prop: "source", label: "告警源", minWidth: 200 },
  { prop: "type", label: "威胁类型", minWidth: 150 },
  { prop: "status", label: "确认状态", minWidth: 150 },
  { prop: "is_handled", label: "处置状态", minWidth: 150 },
  { prop: "updated_time", label: "最近发生时间", minWidth: 180 },
  { prop: "created_time", label: "首次发生时间", minWidth: 180 },
  { prop: "operation", label: "操作", fixed: "right", width: 100 }
]);

const getAssetColumns = async () => {
  if (props.ticketType === "asset") {
    const list: any = [];
    const res = await getAssetFiledApi();
    const data: any = res.data || [];
    data.forEach(item => {
      list.push({
        prop: item.path,
        label: item.name,
        align: "left",
        minWidth: 150
      });
    });
    assetColumns.value = list;
  }
};
// 获取建议明细
const getOpinionList = () => {
  const res: any = [[], []];
  const list = props.ticketData.nodes || [];
  list.forEach(node => {
    (node.results || []).forEach(item => {
      const userList = (node.receiver || []).find(a => Number(a.id) === Number(item.operator)) || {};
      const data: any = {
        time: item.end_time,
        opinion: item.opinion,
        name: userList.username,
        nodeName: node.type === "START" ? "发起人" : node.name,
        nodeType: node.type
      };
      if (node.type === "START") {
        res[0].push(data);
        res[1].push(data);
      } else if (node.type === "REVIEW") {
        res[0].push(data);
      } else if (node.type === "OPERATE") {
        res[1].push(data);
      }
    });
  });
  // 时间倒序排序
  res.forEach((item, i) => {
    opinionList.value[i] = [...item].sort(function (a, b) {
      return b.time.localeCompare(a.time);
    });
  });
};
const getBusinessList = async () => {
  await getBusinessListApi()
    .then(res => {
      const list = res.data.results || [];
      const bList = {};
      list.forEach(item => {
        if (!bList[item.module]) {
          bList[item.module] = [];
        }
        bList[item.module].push(item);
      });
      businessList.value = bList;
    })
    .catch(error => console.log(error));
};
const getWorkflowList = async () => {
  await getWorkflowListApi()
    .then(res => {
      const list = res.data.results || [];
      workflowList.value = baseWorkflow.value.concat(list);
    })
    .catch(error => console.log(error));
};
// 处理表单内容
const handleForm = () => {
  handleBaseForm();
  handleAlarmForm();
};
// 处理告警工单
const handleAlarmForm = () => {
  if (props.ticketType === "alarm") {
    formCustom.name = "业务类型名称" + "_告警发起_" + userName + "_" + nowDate;
    formCustom.source_id = props.alarmInitParams.ids;
    formCustom.source_type = "alarm";
  }
};
// 处理工单
const handleBaseForm = () => {
  if (isNew.value) {
    formCustom.name = props.businessData.name + "_" + userName + "_" + nowDate;
    formCustom.create_at = nowDate;
    formCustom.priority = "1";
    formCustom.create_by = userName;
    formCustom.module = props.businessData.module;
    formCustom.business_id = props.businessData.id;
    formCustom.notes = props.businessData.notes;
    formCustom.workflow = props.businessData.workflow;
    quickOperationList.value = props.businessData.instruction || [];
  } else {
    Object.assign(formCustom, props.ticketData);
    formCustom.status = props.ticketData.status ? statusList[props.ticketData.status] : "";
    formCustom.opinion = "";
  }
  formCustom.business_id = formCustom.business_id ? Number(formCustom.business_id) : undefined;
  formCustom.workflow = formCustom.workflow ? Number(formCustom.workflow) : 0;
};
// 验证表单
const validForm = async () => {
  let res = false;
  const formEl: FormInstance | undefined = formRef.value;
  if (!formEl) return res;
  await formEl.validate(valid => {
    res = valid;
  });
  return res;
};
// 更新上传的文件
const updateFileList = file => {
  formCustom.attachment.push(file);
};
// 删除上传的文件
const deleteFile = i => {
  formCustom.attachment.splice(i, 1);
};
// 下载上传的文件
const downloadFile = async data => {
  try {
    const response = await fetch(data.link);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const blob = await response.blob();
    const downloadUrl = window.URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.href = downloadUrl;
    // 设置下载文件名，可以根据实际情况调整
    link.setAttribute("download", data.name);
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    window.URL.revokeObjectURL(downloadUrl);
  } catch (error) {
    console.error("Download error:", error);
  }
};
// 打开上传的文件
const openFile = data => {
  window.open(data.link);
};

const businessIdChange = () => {
  quickOperationList.value = [];
  if (formCustom.module && formCustom.business_id) {
    const list = (businessList.value[formCustom.module] || []).find(a => Number(a.id) === Number(formCustom.business_id));
    formCustom.workflow = list && list.workflow ? Number(list.workflow) : 0;
    quickOperationList.value = list ? list.instruction : [];
  }
};

watch(
  () => formCustom.source_type,
  data => {
    if (data) {
      rules.source_id = [
        { required: true, message: "不能为空", trigger: "blur" },
        { required: true, message: "长度需为1~288个字符", min: 0, max: 288, trigger: "blur" }
      ];
    } else {
      rules.source_id = [
        { required: false, message: "不能为空", trigger: "blur" },
        { required: false, message: "长度需为0~288个字符", min: 0, max: 288, trigger: "blur" }
      ];
    }
  },
  { deep: true, immediate: true }
);
watch(
  () => props.ticketType,
  () => {
    getAssetColumns();
    getBusinessList();
    getWorkflowList();
  },
  { deep: true, immediate: true }
);
watch(
  () => props.alarmInitParams,
  () => {
    handleAlarmForm();
  },
  { deep: true, immediate: true }
);

const emit = defineEmits(["showFlow"]);
const showFlow = () => {
  emit("showFlow");
};

defineExpose({ validForm, formCustom });

onMounted(() => {
  handleForm();
  getOpinionList();
  getAssetColumns();
  getBusinessList();
  getWorkflowList();
});
</script>

<style lang="scss" scoped>
@import "common";
.ticket-info-main {
  display: flex;
  flex-direction: column;
  row-gap: 16px;
  height: 100%;
  .ticet-title {
    padding: 16px;
    font-size: 18px;
    font-weight: bold;
    color: var(--el-text-color-regular);
    text-align: center;
  }
  .min-title {
    margin: 24px 0 32px;
  }
  .file-block {
    display: flex;
    width: 100%;
    .limit-span {
      margin-left: 16px;
      color: var(--el-icon-color);
    }
    .file-block-content {
      padding: 0 8px;
      overflow: auto;
      .file-block-item {
        .name {
          min-width: 200px;
          text-align: left;
        }
        .icon-down,
        .icon-del {
          display: none;
        }
      }
      .file-block-item:hover {
        .icon-down,
        .icon-del {
          display: inline-block;
        }
      }
    }
  }
  .quick-operation {
    .name {
      margin-right: 12px;
      opacity: 0.65;
    }
  }
  .el-form {
    padding: 8px 0;
  }
  .el-row {
    margin: 0 50px !important;
  }
  .el-form-item--default {
    margin-bottom: 24px;
  }
}
</style>
